package fun.xiefeihong.video.list.conf

import fun.xiefeihong.video.list.handle.TokenHandle
import fun.xiefeihong.video.list.service.impl.UserServiceImpl
import fun.xiefeihong.video.list.utils.RedisUtils
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository

@Configuration
@EnableWebSecurity
class SecurityConf extends WebSecurityConfigurerAdapter{

    static final Logger log = LoggerFactory.getLogger(SecurityConf.class)

    @Value('${spring.redis.host}')
    String host

    @Value('${spring.security.token.validitySeconds}')
    int tokenValiditySeconds

    @Bean
    UserDetailsService userDetailsService(){
        new UserServiceImpl()
    }

    @Bean
    PersistentTokenRepository tokenRepository(){
        def tokenRepository
        def isConnect = RedisUtils.isConnect("redis://${host}")
        if(isConnect){
            tokenRepository = new TokenHandle()
        } else {
            tokenRepository = new InMemoryTokenRepositoryImpl()
        }
        log.info("tokenRepository is: ${tokenRepository.getClass().name}")
        tokenRepository
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        new BCryptPasswordEncoder()
    }

    @Override
    void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).
                passwordEncoder(passwordEncoder())
    }

    @Override
    void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers('/').permitAll()
                .antMatchers('/video/**').hasAuthority('ADMIN')
                .anyRequest().authenticated()
            .and().formLogin()
                .usernameParameter('username')
                .passwordParameter('password')
                .permitAll()
            .and().rememberMe()
                .tokenValiditySeconds(tokenValiditySeconds)
                .tokenRepository(tokenRepository())
            .and().logout()
                .logoutUrl('/logout')
                .permitAll()
    }

    @Override
    void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                '/css/**'
        )
    }

}
